using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using CommonLibraries.DeviceLibrary;
using Distribution.General;
using DistributionApplication.Interface;
using DistributionApplication.Properties;

namespace DistributionApplication.Presenter
{
    public class BasePresenter
    {
        const int m_MinBatteryLevel = 6500;
        const int m_MaxBatteryLevel = 8230;
        protected long m_TotalNumberOfBytes = 0;
        protected long m_TotalNumberOfFreeBytes = 0;
        protected Handheld m_Handheld;

        private IBase m_View;

        public BasePresenter(IBase m_View)
        {
            this.m_View = m_View;
            m_Handheld = Handheld.GetInstance();
        }

        public void Setup()
        {
            if (!File.Exists(PPIConstants.K_DllPath))
            {
                if (!Directory.Exists(PPIConstants.K_WindowsFolder))
                    Directory.CreateDirectory(PPIConstants.K_WindowsFolder);
                byte[] _SourceFile = Resources.TGMS2HELPER;
                if (_SourceFile != null)
                {
                    FileStream _DllFile = File.Create(PPIConstants.K_DllPath);
                    _DllFile.Write(_SourceFile, 0, (int)(_SourceFile.Length));
                    _DllFile.Flush();
                    _DllFile.Close();
                    _DllFile.Dispose();
                }
                else
                    throw new Exception(Constants.K_MissingTGMS2HELPER);
            }

            //If the images folder doesn't exist, create it
            if (!Directory.Exists(PPIConstants.K_ImagesFolder))
                Directory.CreateDirectory(PPIConstants.K_ImagesFolder);

            //If there is no database, throws exception
            //if (!File.Exists(PPIConstants.K_DBPath))
            //{
            //    throw new Exception(String.Format("Database not found. Please verify {0} is located at {1}",PPIConstants.K_DBName,PPIConstants.K_DBPath));
            //}
        }

        /// <summary>
        /// Calculates disk space status from total storage space and free space.
        /// 100% - 51% = Good
        /// 50% - 21% = Low
        /// 20% - 1% = Very Low
        /// </summary>
        public void CheckDisk()
        {

            long _FreeBytesAvailable = 0;
            long _TotalNumberOfBytes = 0;
            long _TotalNumberOfFreeBytes = 0;

            GetDiskFreeSpaceEx(PPIConstants.K_SDCardPath, ref _FreeBytesAvailable, ref _TotalNumberOfBytes, ref _TotalNumberOfFreeBytes);

            int _CurrentPercentage = Convert.ToInt32(_TotalNumberOfFreeBytes * 100 / _TotalNumberOfBytes);

            if (_CurrentPercentage >= 51 && _CurrentPercentage <= 100)
                m_View.DiskStatus = (int)SquareColors.Green;
            else if (_CurrentPercentage < 51 && _CurrentPercentage > 20)
                m_View.DiskStatus = (int)SquareColors.Yellow;
            else
                m_View.DiskStatus = (int)SquareColors.Red;

            m_TotalNumberOfBytes = _TotalNumberOfBytes;
            m_TotalNumberOfFreeBytes = _TotalNumberOfFreeBytes;
        }

        /// <summary>
        /// Returns total number of bytes, number of free bytes and free bytes available for a given path.
        /// </summary>
        [DllImport("coredll")]
        public static extern int GetDiskFreeSpaceEx(string lpDirectoryName, ref long lpFreeBytesAvailable, ref long lpTotalNumberOfBytes, ref long lpTotalNumberOfFreeBytes);

        /// <summary>
        /// Returns an approximation of current battery level (almost always the same value as in the Power
        /// dialog in the Control Panel)
        /// </summary>
        protected double GetEnergyPercentage(Int32 batteryLevel)
        {
            //Created by: VMCoder
            //Creation date: -
            //Last updated by: VMCoder
            //Last update: 2008.04.10

            return Convert.ToDouble((batteryLevel - m_MinBatteryLevel) * 100) / (m_MaxBatteryLevel - m_MinBatteryLevel);
        }
        /// <summary>
        /// Calculates battery level.
        /// 100% - 51% = Good
        /// 50% - 26% = Low
        /// 25% - 1% = Very Low
        /// </summary>
        private void CheckBatteryLevel()
        {
            //Created by: VMCoder
            //Creation date: -
            //Last updated by: VMCoder
            //Last update: 2008.04.10

            int _CurrentLoadPercentage = Convert.ToInt32(GetEnergyPercentage(m_Handheld.BatteryLevel));

            if (_CurrentLoadPercentage >= 51 && _CurrentLoadPercentage <= 100)
                m_View.BatteryStatus = (int)SquareColors.Green;
            else if (_CurrentLoadPercentage < 51 && _CurrentLoadPercentage > 25)
                m_View.BatteryStatus = (int)SquareColors.Yellow;
            else
                m_View.BatteryStatus = (int)SquareColors.Red;
        }
        /// <summary>
        /// Returns White if connected to the power cord, or the corresponding status if not.
        /// </summary>
        public void CheckBattery()
        {
            //Created by: VMCoder
            //Creation date: -
            //Last updated by: VMCoder
            //Last update: 2008.04.10

            if (m_Handheld.PowerSource == PowerSources.Battery)
                CheckBatteryLevel();
            else
                m_View.BatteryStatus = (int)SquareColors.White;
        }

        /// <summary>
        /// Deletes temporary files (i.e., photos taken in a cancelled visit)
        /// </summary>
        public void DeleteTemporaryFiles()
        {
            //Created by: VMCoder
            //Creation date: -
            //Last updated by: VMCoder
            //Last update: 2008.04.10

            foreach (string _File in Directory.GetFiles(PPIConstants.K_ImagesFolder))
                if (_File.IndexOf("temp") > -1)
                    File.Delete(_File);
        }

        /// <summary>
        /// Returns corresponding status color (if applicable)
        /// </summary>
        public Color SetStatus(int status)
        {
            //Created by: GBarzola
            //Creation date: -
            //Last updated by: VMCoder
            //Last update: 2008.04.10

            Color res = Color.Indigo;
            switch (status)
            {
                case 3:
                    res = Color.White;
                    break;
                case 2:
                    res = Color.Yellow;
                    break;
                case 1:
                    res = Color.Lime;
                    break;
                case 0:
                    res = Color.Red;
                    break;
            }
            return res;
        }


        public void ShowDiskStatus(Int32 statusColor)
        {
            string message = "Current Storage Level is unknown";
            switch (statusColor)
            {
                case (Int32)SquareColors.Green:
                    message = string.Format("Current Storage Level is Good ( {0} )", Convert.ToInt32(m_TotalNumberOfFreeBytes * 100 / m_TotalNumberOfBytes));
                    break;
                case (Int32)SquareColors.Yellow:
                    message = string.Format("Current Storage Level is Low ( {0} )", Convert.ToInt32(m_TotalNumberOfFreeBytes * 100 / m_TotalNumberOfBytes));
                    break;
                case (Int32)SquareColors.Red:
                    message = string.Format("Current Storage Level is Very Low ( {0} )", Convert.ToInt32(m_TotalNumberOfFreeBytes * 100 / m_TotalNumberOfBytes));
                    break;
            }
            m_View.ShowMessage(message, PPIConstants.K_AppName);
        }

        public void ShowBatteryStatus(Int32 statusColor)
        {
            string message = "Current Battery Level is unknown";

            switch (statusColor)
            {
                case (Int32)SquareColors.White:
                    message = string.Format("Handheld is connected to Power Plug ( {0}%)",GetEnergyPercentage(m_Handheld.BatteryLevel).ToString("F0"));
                    break;
                case (Int32)SquareColors.Green:
                    message = string.Format("Current Battery Level is Good ( {0}%)", GetEnergyPercentage(m_Handheld.BatteryLevel).ToString("F0"));
                    break;
                case (Int32)SquareColors.Yellow:
                    message = string.Format("Current Battery Level is Low ( {0}%)", GetEnergyPercentage(m_Handheld.BatteryLevel).ToString("F0"));
                    break;
                case (Int32)SquareColors.Red:
                    message = string.Format("Current Battery Level is Very Low ( {0}%)", GetEnergyPercentage(m_Handheld.BatteryLevel).ToString("F0"));
                    break;
            }
            m_View.ShowMessage(message, PPIConstants.K_AppName);


        }
    }
}